package org.orange.feign.simulate.simple.feign.core;

import org.orange.feign.simulate.simple.feign.core.config.ServerUrlTable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

/**
 * @author yuhongtai
 * <p>
 * 负载均衡拦截器
 */

public class LoadBalanceInterceptor implements ClientHttpRequestInterceptor {

    @Autowired
    ServerUrlTable serverUrlTable;

    private Map<String, String> uriMap = new HashMap<>();

    @Override
    public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution execution) throws IOException {
        URI requestUri = httpRequest.getURI();
        String path = requestUri.getPath();
        String[] parts = path.split("/");

        String appName = parts[1];
        String uri = buildUri(parts, path);
        //服务器列表
        List<String> targetUrls = new ArrayList<>(serverUrlTable.get(appName));
        //轮训列表
        //选择其中一台服务器
        int size = targetUrls.size();
        int index = new Random().nextInt(size);
        String targetUrl = targetUrls.get(index);
        //最终服务器地址
        String actualUrl = targetUrl + "/" + uri;

        //默认用jackson转会报错
        List<HttpMessageConverter<?>> messageConverters = Arrays.asList(
                new ByteArrayHttpMessageConverter(),
                new StringHttpMessageConverter());
        URL url = new URL(actualUrl);
        URLConnection urlConnection = url.openConnection();
        InputStream body = urlConnection.getInputStream();
        HttpHeaders headers = new HttpHeaders();
        //execution.execute()
        return new SimpleClientHttpResponse(headers, body);
    }

    private String buildUri(String[] parts, String uri) {
        if (parts == null || parts.length < 3) {
            throw new IllegalArgumentException(String.format("uri拼接失败,原uri: %s", uri));
        }
        if (!uriMap.containsKey(uri)) {
            StringBuilder uriBuilder = new StringBuilder();
            for (int i = 2; i < parts.length; i++) {
                String part = parts[i];
                uriBuilder.append(part).append("/");
            }
            // 删除最后一个 /
            uriBuilder.deleteCharAt(uriBuilder.length() - 1);
            uriMap.put(uri, uriBuilder.toString());
        }
        return uriMap.get(uri);
    }

    class SimpleClientHttpResponse implements ClientHttpResponse {

        private HttpHeaders headers;

        private InputStream body;

        public SimpleClientHttpResponse(HttpHeaders headers, InputStream body) {
            this.headers = headers;
            this.body = body;
        }

        @Override
        public HttpStatus getStatusCode() throws IOException {
            return HttpStatus.OK;
        }

        @Override
        public int getRawStatusCode() throws IOException {
            return 200;
        }

        @Override
        public String getStatusText() throws IOException {
            return "测试用,都是成功";
        }

        @Override
        public void close() {

        }

        @Override
        public InputStream getBody() throws IOException {
            return body;
        }

        @Override
        public HttpHeaders getHeaders() {
            return headers;
        }
    }
}
